import logging
from django.core.exceptions import ObjectDoesNotExist
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework.authentication import TokenAuthentication
from rest_framework.parsers import JSONParser
from rest_framework.views import APIView
from api_test.common.api_response import JsonResponse
from api_test.common.common import record_dynamic
from api_test.models import Project, ApiGroupLevelFirst
from api_test.serializers import ApiGroupLevelFirstSerializer, ApiGroupLevelFirstDeserializer, ProjectListSerializer

logger = logging.getLogger(__name__)  # 这里使用 __name__ 动态搜索定义的 logger 配置，这里有一个层次关系的知识点。


class Group(APIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = ()

    @swagger_auto_schema(manual_parameters=[
        openapi.Parameter(name="project_id", in_=openapi.IN_QUERY, type=openapi.TYPE_INTEGER, description="项目id"),
        openapi.Parameter(name="name", in_=openapi.IN_QUERY, type=openapi.TYPE_STRING, description="模块名称"),
    ])
    def get(self, request):
        """
        接口模块
        """
        project_id = request.GET.get("project_id")
        name = request.GET.get("name")
        # 校验参数
        if not project_id:
            return JsonResponse(code="999996", msg="参数有误!")
        if not project_id.isdecimal():
            return JsonResponse(code="999996", msg="参数有误!")
        # 验证项目是否存在
        try:
            pro_data = Project.objects.get(id=project_id)
        except ObjectDoesNotExist:
            return JsonResponse(code="999995", msg="项目不存在!")
        # 序列化结果
        pro_data = ProjectListSerializer(pro_data)
        # 校验项目状态
        if not pro_data.data["status"]:
            return JsonResponse(code="999985", msg="该项目已禁用")
        # 查找项目下所有接口信息，并按id排序，序列化结果
        obi = ApiGroupLevelFirst.objects.filter(project=project_id, status=True)
        if name:
            obi = obi.filter(name__icontains=name).order_by("id")
        obi = obi.order_by("id")

        serialize = ApiGroupLevelFirstSerializer(obi, many=True)
        return JsonResponse(data=serialize.data, code="999999", msg="成功!")


class AddGroup(APIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = ()

    def parameter_check(self, data):
        """
        校验参数
        """
        try:
            # 必传参数 name
            if not data.get("name") or not data.get("project_id"):
                return JsonResponse(code="999996", msg="参数有误!")
            # 校验project_id类型为int
            if not isinstance(data["project_id"], int):
                return JsonResponse(code="999996", msg="参数有误!")
        except KeyError:
            return JsonResponse(code="999996", msg="参数有误!")

    @swagger_auto_schema(request_body=openapi.Schema(
        type=openapi.TYPE_OBJECT,
        required=['project_id', 'name'],
        properties={
            'project_id': openapi.Schema(type=openapi.TYPE_INTEGER, description="项目id"),
            'name': openapi.Schema(type=openapi.TYPE_STRING, description="接口模块名称"),
            'description': openapi.Schema(type=openapi.TYPE_STRING, description="接口模块描述")
        },
    ))
    def post(self, request):
        """
        新增接口模块
        """
        data = JSONParser().parse(request)
        result = self.parameter_check(data)
        if result:
            return result
        # 校验项目状态
        try:
            obj = Project.objects.get(id=data["project_id"])
            if not request.user.is_superuser and obj.user.is_superuser:
                return JsonResponse(code="999983", msg="无操作权限！")
        except ObjectDoesNotExist:
            return JsonResponse(code="999995", msg="项目不存在!")
        pro_data = ProjectListSerializer(obj)
        if not pro_data.data["status"]:
            return JsonResponse(code="999985", msg="该项目已禁用")

        count = ApiGroupLevelFirst.objects.filter(name=data["name"], project=data["project_id"]).count()
        if count > 0:
            return JsonResponse(code="999997", msg="存在相同名称！")
        else:
            # 反序列化
            serializer = ApiGroupLevelFirstDeserializer(data=data)
            # 校验反序列化正确，正确则保存，外键为project
            if serializer.is_valid():
                serializer.save(project=obj)
            else:
                return JsonResponse(code="999998", msg="失败!")
            # 新增接口操作
            record_dynamic(project=serializer.data.get("project_id"),
                           _type="添加", operationObject="接口模块", user=request.user.pk,
                           data="新增接口模块“%s”" % data["name"])
            return JsonResponse(data={
                "group_id": serializer.data.get("id")
            }, code="999999", msg="成功!")


class UpdateNameGroup(APIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = ()

    def parameter_check(self, data):
        """
        校验参数
        """
        try:
            # 必传参数 name
            if not data.get("project_id") or not data.get("id") or not data.get("name"):
                return JsonResponse(code="999996", msg="参数有误!")
            # 校验project_id, id类型为int
            if not isinstance(data["project_id"], int) or not isinstance(data["id"], int):
                return JsonResponse(code="999996", msg="参数有误!")
        except KeyError:
            return JsonResponse(code="999996", msg="参数有误!")

    @swagger_auto_schema(request_body=openapi.Schema(
        type=openapi.TYPE_OBJECT,
        required=['id', 'project_id', 'name'],
        properties={
            'id': openapi.Schema(type=openapi.TYPE_INTEGER, description="接口模块id"),
            'project_id': openapi.Schema(type=openapi.TYPE_INTEGER, description="项目id"),
            'name': openapi.Schema(type=openapi.TYPE_STRING, description="接口模块名称"),
            'description': openapi.Schema(type=openapi.TYPE_STRING, description="接口模块描述")
        },
    ))
    def post(self, request):
        """
        修改接口模块名称
        """
        data = JSONParser().parse(request)
        result = self.parameter_check(data)
        if result:
            return result
        try:
            pro_data = Project.objects.get(id=data["project_id"])
            if not request.user.is_superuser and pro_data.user.is_superuser:
                return JsonResponse(code="999983", msg="无操作权限！")
        except ObjectDoesNotExist:
            return JsonResponse(code="999995", msg="项目不存在!")
        pro_data = ProjectListSerializer(pro_data)
        if not pro_data.data["status"]:
            return JsonResponse(code="999985", msg="该项目已禁用")
        try:
            obj = ApiGroupLevelFirst.objects.get(id=data["id"], project=data["project_id"])
        except ObjectDoesNotExist:
            return JsonResponse(code="999991", msg="模块不存在!")
        serializer = ApiGroupLevelFirstDeserializer(data=data)
        if serializer.is_valid():
            serializer.update(instance=obj, validated_data=data)
        else:
            return JsonResponse(code="999998", msg="失败!")
        record_dynamic(project=data.get("project_id"),
                       _type="修改", operationObject="接口模块", user=request.user.pk,
                       data="修改接口模块“%s”" % data["name"])
        return JsonResponse(code="999999", msg="成功!")


class DelGroup(APIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = ()

    def parameter_check(self, data):
        """
        校验参数
        """
        try:
            if not data.get("project_id") or not data.get("ids"):
                return JsonResponse(code="999996", msg="参数有误!")
            # 校验project_id, id类型为int
            if not isinstance(data["ids"], list) or not isinstance(data["project_id"], int):
                for i in data["ids"]:
                    if not isinstance(i, int) or not isinstance(int(i), int):
                        return JsonResponse(code="999995", msg="参数有误！")
                return JsonResponse(code="999995", msg="参数有误！")
        except KeyError:
            return JsonResponse(code="999996", msg="参数有误!")

    @swagger_auto_schema(request_body=openapi.Schema(
        type=openapi.TYPE_OBJECT,
        required=['project_id', 'ids'],
        properties={
            'project_id': openapi.Schema(type=openapi.TYPE_INTEGER, description="项目id"),
            'ids': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Items(type=openapi.TYPE_INTEGER),
                                  description="待删除待接口模块 id列表"),
        },
    ))
    def post(self, request):
        """
        删除(禁用)接口模块名称
        """
        data = JSONParser().parse(request)
        result = self.parameter_check(data)
        if result:
            return result
        try:
            pro_data = Project.objects.get(id=data["project_id"])
            if not request.user.is_superuser and pro_data.user.is_superuser:
                return JsonResponse(code="999983", msg="无操作权限！")
        except ObjectDoesNotExist:
            return JsonResponse(code="999995", msg="项目不存在!")
        pro_data = ProjectListSerializer(pro_data)
        if not pro_data.data["status"]:
            return JsonResponse(code="999985", msg="该项目已禁用")
        # 根据项目id和模块 id查找，若存在则删除
        try:
            for j in data["ids"]:
                obj = ApiGroupLevelFirst.objects.get(id=j, project=data["project_id"])
                if obj:
                    # obj.delete()  # 删除
                    obj.status = False
                    obj.save()
                    record_dynamic(project=data["project_id"], _type="禁用", operationObject="接口模块", user=request.user.pk, data="禁用接口模块“%s”" % obj.name)
            return JsonResponse(code="999999", msg="成功！")
        except ObjectDoesNotExist:
            return JsonResponse(code="999995", msg="模块不存在！")
